#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unity.h"
#include "mock_bsp_test_commom.h"  // 假设这是包含rt_ATRWrite和rt_ATCRead声明的头文件

#include "rt_AcqTrans_proc.h"

// 被测函数声明
void rt_AcqTrans_proc(XRt1553B *InstancePtr, XRt1553B_MsgBlkDesc *CMDInfo, B1553_BusService *pBusServ);




// 全局测试变量
XRt1553B g_Instance;
XRt1553B_MsgBlkDesc g_CMDInfo;
B1553_BusService g_BusServ;

// 测试初始化函数
void setUp(void) {
    // 每个测试前重置全局变量
    memset(&g_Instance, 0, sizeof(g_Instance));
    memset(&g_CMDInfo, 0, sizeof(g_CMDInfo));
    memset(&g_BusServ, 0, sizeof(g_BusServ));
    
}

void tearDown(void) {

}

// TC001: T_or_R=1, 超时计数≤阈值或已复位 -> 仅增加超时计数
void test_rt_AcqTrans_proc_timeout_no_reset(void) {
    // Arrange
    g_CMDInfo.T_or_R = 1;
    g_BusServ.AcqTransTimeOut = 3;  // < CCSDS_ATC_TIMEOUT
    g_BusServ.AcqTransReady = 1;    // 已经准备好
    
    u16 expected_timeout = g_BusServ.AcqTransTimeOut + 1;
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(expected_timeout, g_BusServ.AcqTransTimeOut);
}

// TC002: T_or_R=1, 超时计数>阈值且未复位 -> 执行协议复位操作
void test_rt_AcqTrans_proc_timeout_with_reset(void) {
    // Arrange
    g_CMDInfo.T_or_R = 1;
    g_BusServ.AcqTransTimeOut = 26;  // > CCSDS_ATC_TIMEOUT
    g_BusServ.AcqTransReady = 1;    // 未复位状态
    
    // 设置期望的回调
    rt_ATRWrite_ExpectAnyArgs();
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_AcqBlkCnt);
    TEST_ASSERT_EQUAL(CCSDS_ATR_RESET, g_BusServ.AcqTransReq_ctrl);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_bytes);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReady);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransTimeOut);

}

// TC003: T_or_R≠1, 复位状态，收到正确复位确认 -> 退出复位状态
void test_rt_AcqTrans_proc_reset_state_correct_ack(void) {
    // Arrange
    g_CMDInfo.T_or_R = 0;
    g_BusServ.AcqTransReady = 0;          // 复位状态
    g_BusServ.AcqTransCfm_bytes = 0;      // 正确的字节确认
    g_BusServ.AcqTransCfm_ctrl = CCSDS_ATC_RESET;  // 正确的控制确认
    
    // 设置期望的回调
    rt_ATCRead_ExpectAnyArgs();
    rt_ATRWrite_ExpectAnyArgs();
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_AcqBlkCnt);
    TEST_ASSERT_EQUAL(CCSDS_TRCTRL_RUNNING, g_BusServ.AcqTransReq_ctrl);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_bytes);
    TEST_ASSERT_EQUAL(1, g_BusServ.AcqTransReady);  // 应该退出复位状态
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransTimeOut);

}

// TC004: T_or_R≠1, 复位状态，未收到复位确认 -> 保持复位状态
void test_rt_AcqTrans_proc_reset_state_no_ack(void) {
    // Arrange
    g_CMDInfo.T_or_R = 0;
    g_BusServ.AcqTransReady = 0;           // 复位状态
    g_BusServ.AcqTransCfm_bytes = 10;      // 错误的字节确认
    g_BusServ.AcqTransCfm_ctrl = 0x0000;   // 错误的控制确认
    
    // 设置期望的回调
    rt_ATCRead_ExpectAnyArgs();
    rt_ATRWrite_ExpectAnyArgs();
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_AcqBlkCnt);
    TEST_ASSERT_EQUAL(CCSDS_ATR_RESET, g_BusServ.AcqTransReq_ctrl);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_bytes);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReady);  // 应该保持复位状态
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransTimeOut);
}

// TC005: T_or_R≠1, 正常状态，ATC与ATR数据一致 -> 传输完成，恢复初始状态
void test_rt_AcqTrans_proc_normal_state_data_match(void) {
    // Arrange
    g_CMDInfo.T_or_R = 0;
    g_BusServ.AcqTransReady = 1;              // 正常状态
    g_BusServ.AcqTransCfm_ctrl = 0x1234;      // 与请求相同
    g_BusServ.AcqTransReq_ctrl = 0x1234;
    g_BusServ.AcqTransCfm_bytes = 0x5678;     // 与请求相同
    g_BusServ.AcqTransReq_bytes = 0x5678;
    
    // 设置期望的回调
    rt_ATCRead_ExpectAnyArgs();
    rt_ATRWrite_ExpectAnyArgs();
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransTimeOut);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReq_bytes);
    TEST_ASSERT_EQUAL(CCSDS_TRCTRL_RUNNING, g_BusServ.AcqTransReq_ctrl);
    TEST_ASSERT_EQUAL(1, g_BusServ.AcqTransReady);

}

// TC006: T_or_R≠1, 正常状态，ATC与ATR数据不一致 -> 维持当前状态
void test_rt_AcqTrans_proc_normal_state_data_mismatch(void) {
    // Arrange
    g_CMDInfo.T_or_R = 0;
    g_BusServ.AcqTransReady = 1;              // 正常状态
    g_BusServ.AcqTransCfm_ctrl = 0x1234;      // 与请求不同
    g_BusServ.AcqTransReq_ctrl = 0x5678;
    g_BusServ.AcqTransCfm_bytes = 0x9ABC;     // 与请求不同
    g_BusServ.AcqTransReq_bytes = 0xDEF0;
    
    // 设置期望的回调
    rt_ATCRead_ExpectAnyArgs();
    // 不期望调用rt_ATRWrite因为状态没有改变
    
    // 记录原始状态
    u16 original_timeout = g_BusServ.AcqTransTimeOut;
    u16 original_ready = g_BusServ.AcqTransReady;
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(original_timeout, g_BusServ.AcqTransTimeOut);  // 应该不变
    TEST_ASSERT_EQUAL(original_ready, g_BusServ.AcqTransReady);      // 应该不变
}


// TC007: AcqTransTimeOut == CCSDS_ATC_TIMEOUT (boundary) -> only increment timeout
void test_rt_AcqTrans_proc_timeout_at_boundary_no_reset(void) {
    // Arrange
    g_CMDInfo.T_or_R = 1;
    g_BusServ.AcqTransTimeOut = 25;  // Exactly at boundary
    g_BusServ.AcqTransReady = 1;    // Ready state
    
    u16 expected_timeout = 0;

    rt_ATRWrite_ExpectAnyArgs();
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(expected_timeout, g_BusServ.AcqTransTimeOut);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReady);  // Should remain unchanged

}

// // // TC008: AcqTransTimeOut == (CCSDS_ATC_TIMEOUT - 1) and AcqTransReady == 1 -> execute reset
void test_rt_AcqTrans_proc_timeout_at_boundary_no_reset2(void) {
    // Arrange
    g_CMDInfo.T_or_R = 1;
    g_BusServ.AcqTransTimeOut = 24;  // Exactly at boundary
    g_BusServ.AcqTransReady = 1;    // Ready state
    
    u16 expected_timeout = 25;


    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(expected_timeout, g_BusServ.AcqTransTimeOut);
    TEST_ASSERT_EQUAL(1, g_BusServ.AcqTransReady);  // Should remain unchanged

}


// TC009: Already in reset state with timeout -> only increment timeout
void test_rt_AcqTrans_proc_timeout_while_in_reset_state(void) {
    // Arrange
    g_CMDInfo.T_or_R = 1;
    g_BusServ.AcqTransTimeOut = 3;
    g_BusServ.AcqTransReady = 0;    // Already in reset state
    
    u16 expected_timeout = g_BusServ.AcqTransTimeOut + 1;
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(expected_timeout, g_BusServ.AcqTransTimeOut);
    TEST_ASSERT_EQUAL(0, g_BusServ.AcqTransReady);  // Should remain in reset state
}

// TC010: Data mismatch with specific patterns -> maintain state
void test_rt_AcqTrans_proc_normal_state_data_mismatch_specific(void) {
    // Arrange
    g_CMDInfo.T_or_R = 0;
    g_BusServ.AcqTransReady = 1;
    g_BusServ.AcqTransCfm_ctrl = 0xFFFF;      // Opposite values
    g_BusServ.AcqTransReq_ctrl = 0x0000;
    g_BusServ.AcqTransCfm_bytes = 0xAAAA;
    g_BusServ.AcqTransReq_bytes = 0x5555;
    
    // Set expectations
    rt_ATCRead_ExpectAnyArgs();
    // Should not call ATRWrite as state doesn't change
    
    u16 original_timeout = g_BusServ.AcqTransTimeOut;
    u16 original_ready = g_BusServ.AcqTransReady;
    
    // Act
    rt_AcqTrans_proc(&g_Instance, &g_CMDInfo, &g_BusServ);
    
    // Assert
    TEST_ASSERT_EQUAL(original_timeout, g_BusServ.AcqTransTimeOut);
    TEST_ASSERT_EQUAL(original_ready, g_BusServ.AcqTransReady);
}